#include "domain.h"
#include "ui_domain.h"

Domain::Domain(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Domain)
{
    ui->setupUi(this);
    initUI();
    m_sptr_modelLoader = std::make_shared<ModelFileLoader>();
}

Domain::~Domain()
{
    delete ui;
}

void Domain::initUI()
{
    fLabCurFile = new QLabel;
    fLabCurFile->setMinimumWidth(150);
    fLabCurFile->setText("当前文件：");
    ui->statusbar->addWidget(fLabCurFile);

    ui->actionPreview->setEnabled(false);
    ui->actionSaveAs->setEnabled(false);
    ui->actionViewPortMatched->setEnabled(false);
    ui->actionViewPortFilled->setEnabled(false);
    ui->actionContoursExtraction->setEnabled(false);
    ui->grayScaleSettingMenu->setEnabled(false);
    ui->colorSettingMenu->setEnabled(false);
    ui->actionPreview->setEnabled(false);
    ui->actionModelScaling->setEnabled(false);
}

void Domain::refreshUI()
{
    // 启用定向预览菜单选项
    ui->actionPreview->setEnabled(true);
    ui->actionSaveAs->setEnabled(true);
    ui->actionViewPortMatched->setEnabled(true);
    ui->actionViewPortFilled->setEnabled(true);
    ui->actionContoursExtraction->setEnabled(true);
    ui->grayScaleSettingMenu->setEnabled(true);
    ui->colorSettingMenu->setEnabled(true);
    ui->actionPreview->setEnabled(true);
    ui->actionModelScaling->setEnabled(true);
}

void Domain::initConnections()
{
    disconnect(m_sptr_modelColorPalette.get(), &ModelColorPalette::colorConfirmed, nullptr, nullptr);
    disconnect(m_sptr_snapShotSetting.get(), &SnapShotSettingDialog::accepted, nullptr, nullptr);
    disconnect(m_sptr_slicingSetting.get(), &SlicingSettingsDialog::slicingSettingsConfirmed, nullptr, nullptr);
    disconnect(m_sptr_previewDirectionSelector.get(), &PreviewDirectionSelector::updateCameraView, nullptr, nullptr);

    connect(m_sptr_modelColorPalette.get(), &ModelColorPalette::colorConfirmed, m_sptr_modelDisplayer.get(), &ModelDisplayer::setPureColor);
    connect(m_sptr_snapShotSetting.get(), &SnapShotSettingDialog::accepted, this, [this](){
        qsizetype res_width = m_sptr_snapShotSetting->getResWidth();
        qsizetype res_height = m_sptr_snapShotSetting->getResHeight();
        auto file_name = m_sptr_snapShotSetting->getFileName();
        auto file_format = m_sptr_snapShotSetting->getFileFormat(); // TODO(mengjinlang): 需要一个文件管理类，重构存储接口才用得上（目前只支持PNG），先留着
        m_sptr_modelDisplayer->saveFramebufferToImage(file_name + "." + file_format, file_format, res_width, res_height);
    });
    connect(m_sptr_previewDirectionSelector.get(), &PreviewDirectionSelector::updateCameraView, m_sptr_modelDisplayer.get(), [this](){
        m_sptr_modelDisplayer->update();
    });
    connect(m_sptr_slicingSetting.get(), &SlicingSettingsDialog::slicingSettingsConfirmed, this, [this](float stride){
        QVector3D u_axis = QVector3D::crossProduct(m_sptr_viewCamera->getUp(), m_sptr_viewCamera->getEye().normalized()).normalized();
        QVector3D v_axis = QVector3D::crossProduct(m_sptr_viewCamera->getEye().normalized(), u_axis).normalized();
        m_sptr_modelAlgoManager->extractModelContours(m_sptr_modelLoader->hasTexture(),
                                                      m_sptr_modelLoader->getTriangles(),
                                                      m_sptr_modelLoader->getEdges(),
                                                      m_sptr_viewCamera->getEye().normalized(),
                                                      u_axis,
                                                      v_axis,
                                                      stride);
    });
    connect(m_sptr_modelAlgoManager.get(), &ModelAlgoManager::sendProcessedContours, m_sptr_modelDisplayer.get(), &ModelDisplayer::showProcessedPointCloud);
}

void Domain::initModelWidget()
{
    m_sptr_snapShotSetting.reset();
    m_sptr_modelColorPalette.reset();
    m_sptr_previewDirectionSelector.reset();
    m_sptr_slicingSetting.reset();
    m_sptr_viewCamera.reset();
    m_sptr_modelDisplayer.reset();
    m_sptr_modelAlgoManager.reset();

    m_sptr_modelAlgoManager = std::make_shared<ModelAlgoManager>();
    m_sptr_viewCamera = std::make_shared<ViewCamera>();
    m_sptr_modelDisplayer = std::make_shared<ModelDisplayer>(m_sptr_modelLoader, m_sptr_viewCamera);
    m_sptr_snapShotSetting = std::make_shared<SnapShotSettingDialog>(m_sptr_modelDisplayer.get());
    m_sptr_slicingSetting = std::make_shared<SlicingSettingsDialog>(m_sptr_modelDisplayer.get());
    m_sptr_modelColorPalette = std::make_shared<ModelColorPalette>(m_sptr_modelDisplayer.get());
    m_sptr_previewDirectionSelector = std::make_shared<PreviewDirectionSelector>(m_sptr_viewCamera);
    setCentralWidget(m_sptr_modelDisplayer.get());

    m_sptr_modelDisplayer->show();
}

void Domain::updateCurrentFileLabel(const QString &stl_file_path)
{
    QFileInfo fileInfo(stl_file_path);
    QString fileName = fileInfo.fileName();

    // 更新文件名显示
    fLabCurFile->setText(QString("当前文件: %1").arg(fileName));
    fLabCurFile->setToolTip(stl_file_path);

    // 更新文件大小显示
    qint64 size = fileInfo.size();
    QString sizeText;
    // if (size < 1024) {
    //     sizeText = QString("%1 字节").arg(size);
    // } else if (size < 1024 * 1024) {
    //     sizeText = QString("%1 KB").arg(size / 1024);
    // } else {
    //     sizeText = QString("%1 MB").arg(size / (1024 * 1024), 1, 'f', 2);
    // }

    // 更新窗口标题
    setWindowTitle(QString("%1 - 3D Viewer").arg(fileName));
}

void Domain::on_actionOpenFile_triggered()
{
    // 获取用户选择的文件路径
    QString filePath = QFileDialog::getOpenFileName(this, tr("打开3D模型文件"), QDir::homePath(), tr("3D模型文件 (*.stl *.STL *.glb *.GLB *.obj *.OBJ);;所有文件 (*.*)"));

    if (filePath.isEmpty())
        return;  // 用户取消了选择

    try {
        // 尝试读取STL文件
        bool success = m_sptr_modelLoader->load(filePath);

        // 检查模型属性
        // m_sptr_modelLoader->debugCheckModelData();

        if (!success)
        {
            QMessageBox::warning(this, tr("错误"), m_sptr_modelLoader->lastError());
            return;
        }

        // 文件读取成功，初始化模型显示控件
        initModelWidget();

        // 初始化各 connections
        initConnections();

        // 修改状态栏文本
        updateCurrentFileLabel(filePath);

        // 使能各项功能按钮
        refreshUI();
    }
    catch (const std::exception &e)
    {
        QMessageBox::critical(this, tr("错误"),
                              tr("读取模型文件时发生错误: %1").arg(e.what()));
    }
}

void Domain::on_actionViewPortMatched_triggered()
{
    m_sptr_modelDisplayer->setModelViewPortMatched();
}


void Domain::on_actionViewPortFilled_triggered()
{
    m_sptr_modelDisplayer->setModelViewPortFilled(this->width(), this->height(), ProjectionType::Perspective);
}

void Domain::on_actionSaveAs_triggered()
{
    m_sptr_snapShotSetting->show();
}

// #include <QJsonArray>
// #include <QJsonObject>
// #include <QJsonDocument>
// #include <QFile>

// void save3DContoursToJson(
//     const QVector<QVector<QVector<Vertex>>> &resultant_contours,
//     const QVector<float> &slice_lambdas,
//     const QVector3D &plane_norm,
//     const QString &filename)
// {
//     QJsonObject root_object;

//     // 添加元数据
//     QJsonObject metadata;
//     metadata["total_slices"] = resultant_contours.size();
//     metadata["plane_normal_x"] = plane_norm.x();
//     metadata["plane_normal_y"] = plane_norm.y();
//     metadata["plane_normal_z"] = plane_norm.z();
//     root_object["metadata"] = metadata;

//     // 添加切片数据
//     QJsonArray slices_array;

//     for (int i = 0; i < resultant_contours.size(); ++i) {
//         const auto &slice = resultant_contours[i];
//         QJsonObject slice_object;

//         // 切片信息
//         slice_object["slice_index"] = i;
//         slice_object["lambda_value"] = slice_lambdas[i];

//         // 轮廓数据
//         QJsonArray contours_array;
//         for (const auto &contour : slice) {
//             QJsonArray contour_array;
//             for (const auto &pt : contour) {
//                 QJsonObject point_obj;

//                 // 位置坐标
//                 QJsonArray pos_array;
//                 pos_array.append(pt.pos.x());
//                 pos_array.append(pt.pos.y());
//                 pos_array.append(pt.pos.z());
//                 point_obj["position"] = pos_array;

//                 // 颜色信息：交换 R 和 B 通道
//                 QJsonArray color_array;
//                 float originalR = pt.color.x();
//                 float originalG = pt.color.y();
//                 float originalB = pt.color.z();
//                 float originalA = pt.color.w();

//                 // 交换 R 和 B：将 (R,G,B,A) 改为 (B,G,R,A)
//                 color_array.append(originalB); // 原 B → 新 R
//                 color_array.append(originalG); // G 不变
//                 color_array.append(originalR); // 原 R → 新 B
//                 color_array.append(originalA); // A 不变
//                 point_obj["color"] = color_array;

//                 contour_array.append(point_obj);
//             }
//             contours_array.append(contour_array);
//         }

//         slice_object["contours"] = contours_array;
//         slices_array.append(slice_object);
//     }

//     root_object["slices"] = slices_array;

//     QJsonDocument doc(root_object);
//     QFile file(filename);
//     if (file.open(QIODevice::WriteOnly)) {
//         file.write(doc.toJson(QJsonDocument::Indented));
//         file.close();
//     }
// }

// // 注意：新增 u_axis 和 v_axis 参数，用于调用 convertToStacksFormation
// void save3DContoursToJson(
//     const QVector<QVector<QVector<Vertex>>> &processed_contours,  // 处理后的3D轮廓（输入）
//     const QVector<float> &slice_lambdas,
//     const QVector3D &plane_norm,
//     const QVector3D &u_axis,  // 新增：投影u轴（基于法向量(1,0,0)计算）
//     const QVector3D &v_axis,  // 新增：投影v轴（基于法向量(1,0,0)计算）
//     const QString &filename)
// {
//     QJsonObject root_object;

//     // 1. 元数据：保留原有字段，新增u/v轴信息（方便调试，Python可忽略）
//     QJsonObject metadata;
//     metadata["total_slices"] = processed_contours.size();
//     metadata["plane_normal_x"] = plane_norm.x();
//     metadata["plane_normal_y"] = plane_norm.y();
//     metadata["plane_normal_z"] = plane_norm.z();
//     metadata["u_axis_x"] = u_axis.x();
//     metadata["u_axis_y"] = u_axis.y();
//     metadata["u_axis_z"] = u_axis.z();
//     metadata["v_axis_x"] = v_axis.x();
//     metadata["v_axis_y"] = v_axis.y();
//     metadata["v_axis_z"] = v_axis.z();
//     root_object["metadata"] = metadata;

//     // 2. 调用 convertToStacksFormation 转换为 2D 投影轮廓（核心修改）
//     QVector<QVector<QVector<QPointF>>> stacks_2d =
//         ContourProcessing::ContourProcessor::convertToStacksFormation(processed_contours, u_axis, v_axis);

//     // 3. 保存转换后的 2D 点（替换原3D点）
//     QJsonArray slices_array;
//     for (int i = 0; i < stacks_2d.size(); ++i) {
//         const auto &slice_2d = stacks_2d[i];  // 单个切片的2D轮廓集
//         QJsonObject slice_object;

//         // 切片基础信息（与原逻辑一致）
//         slice_object["slice_index"] = i;
//         slice_object["lambda_value"] = slice_lambdas[i];

//         // 轮廓数据：保存2D点（u, v）
//         QJsonArray contours_array;
//         for (const auto &contour_2d : slice_2d) {  // 单个2D轮廓
//             QJsonArray contour_array;
//             for (const auto &pt_2d : contour_2d) {  // 单个2D点（QPointF）
//                 QJsonObject point_obj;

//                 // 关键：保存投影后的2D坐标（u, v），仍用"position"字段兼容Python
//                 QJsonArray pos_array;
//                 pos_array.append(pt_2d.x());  // u坐标（对应convertToStacksFormation的u_coord）
//                 pos_array.append(pt_2d.y());  // v坐标（对应convertToStacksFormation的v_coord）
//                 pos_array.append(slice_lambdas[i]);       // 占位Z值（Python读取时忽略，不破坏数组结构）
//                 point_obj["position"] = pos_array;

//                 // 颜色信息：保持原逻辑（交换R和B通道，兼容Python颜色解析）
//                 QJsonArray color_array;
//                 // 从原始3D轮廓中取颜色（processed_contours与stacks_2d结构完全一致）
//                 if (i < processed_contours.size() &&  // 边界容错
//                     &contour_2d - &slice_2d[0] < processed_contours[i].size() &&
//                     &pt_2d - &contour_2d[0] < processed_contours[i][&contour_2d - &slice_2d[0]].size()) {
//                     const Vertex &original_vertex = processed_contours[i][&contour_2d - &slice_2d[0]][&pt_2d - &contour_2d[0]];
//                     float originalR = original_vertex.color.x();
//                     float originalG = original_vertex.color.y();
//                     float originalB = original_vertex.color.z();
//                     float originalA = original_vertex.color.w();
//                     color_array.append(originalB);  // 原B → 新R
//                     color_array.append(originalG);  // G不变
//                     color_array.append(originalR);  // 原R → 新B
//                     color_array.append(originalA);  // A不变
//                 } else {
//                     color_array.append(1.0f);  // 容错：默认白色
//                     color_array.append(1.0f);
//                     color_array.append(1.0f);
//                     color_array.append(1.0f);
//                 }
//                 point_obj["color"] = color_array;

//                 contour_array.append(point_obj);
//             }
//             contours_array.append(contour_array);
//         }

//         slice_object["contours"] = contours_array;
//         slices_array.append(slice_object);
//     }

//     root_object["slices"] = slices_array;

//     // 保存文件
//     QJsonDocument doc(root_object);
//     QFile file(filename);
//     if (file.open(QIODevice::WriteOnly)) {
//         file.write(doc.toJson(QJsonDocument::Indented));
//         file.close();
//         qDebug() << "2D投影轮廓已保存到：" << filename;
//     } else {
//         qWarning() << "无法保存JSON文件：" << filename;
//     }
// }

// void save3DContoursToJson(
//     const QVector<QVector<QVector<Vertex>>> &resultant_contours,
//     const QVector<float> &slice_lambdas,
//     const QVector3D &plane_norm,
//     const QString &filename)
// {
//     QJsonArray output_data;

//     for (int slice_idx = 0; slice_idx < resultant_contours.size(); ++slice_idx) {
//         const auto &slice_contours = resultant_contours[slice_idx];
//         QJsonArray slice_output;

//         for (const auto &contour : slice_contours) {
//             QJsonArray contour_output;

//             for (const auto &vertex : contour) {
//                 QJsonObject point_obj;

//                 // 位置信息（与Python版本一致）
//                 QJsonArray pos_array;
//                 pos_array.append(vertex.pos.x());
//                 pos_array.append(vertex.pos.y());
//                 pos_array.append(vertex.pos.z());
//                 point_obj["position"] = pos_array;

//                 // 添加灰度值作为单独字段
//                 float grayValue = 255.0f * (0.299f * vertex.color.x() + 0.587f * vertex.color.y() + 0.114f * vertex.color.z());
//                 point_obj["grayscale"] = static_cast<float>(grayValue);

//                 contour_output.append(point_obj);
//             }

//             slice_output.append(contour_output);
//         }

//         output_data.append(slice_output);
//     }

//     QJsonDocument doc(output_data);
//     QFile file(filename);
//     if (file.open(QIODevice::WriteOnly)) {
//         file.write(doc.toJson(QJsonDocument::Indented));
//         file.close();
//         qDebug() << "处理后的数据已保存到" << filename;

//         int total_points = 0;
//         for (const auto &slice : resultant_contours) {
//             for (const auto &contour : slice) {
//                 total_points += contour.size();
//             }
//         }
//         qDebug() << "共" << resultant_contours.size() << "个切片，总点数：" << total_points;
//     } else {
//         qWarning() << "无法打开文件进行写入：" << filename;
//     }
// }

// // 辅助函数：绕轴旋转向量
// QVector3D rotateVector(const QVector3D& vector, const QVector3D& axis, float angle)
// {
//     float cosAngle = cos(angle);
//     float sinAngle = sin(angle);

//     // 罗德里格斯旋转公式
//     QVector3D result = vector * cosAngle +
//                        QVector3D::crossProduct(axis, vector) * sinAngle +
//                        axis * QVector3D::dotProduct(axis, vector) * (1 - cosAngle);

//     return result;
// }

// // 辅助函数：旋转轮廓中的所有顶点
// void rotateContours(QVector<QVector<Vertex>>& contours, const QVector3D& axis, float angle)
// {
//     for (auto& contour : contours) {
//         for (auto& vertex : contour) {
//             QVector3D pos(vertex.pos.x(), vertex.pos.y(), vertex.pos.z());
//             QVector3D rotatedPos = rotateVector(pos, axis, angle);
//             vertex.pos = rotatedPos;
//         }
//     }
// }

// // 辅助函数：去除重复顶点
// void removeDuplicateVertices(QVector<QVector<Vertex>>& contours, float threshold)
// {
//     const float thresholdSquared = threshold * threshold;

//     for (auto& contour : contours) {
//         QVector<Vertex> uniqueVertices;

//         for (const auto& vertex : contour) {
//             bool isDuplicate = false;

//             for (const auto& uniqueVertex : uniqueVertices) {
//                 float dx = vertex.pos.x() - uniqueVertex.pos.x();
//                 float dy = vertex.pos.y() - uniqueVertex.pos.y();
//                 float dz = vertex.pos.z() - uniqueVertex.pos.z();
//                 float distanceSquared = dx*dx + dy*dy + dz*dz;

//                 if (distanceSquared < thresholdSquared) {
//                     isDuplicate = true;
//                     break;
//                 }
//             }

//             if (!isDuplicate) {
//                 uniqueVertices.append(vertex);
//             }
//         }

//         contour = uniqueVertices;
//     }

//     // 移除空轮廓
//     contours.erase(std::remove_if(contours.begin(), contours.end(),
//                                   [](const QVector<Vertex>& contour) { return contour.isEmpty(); }),
//                    contours.end());
// }

// void Domain::on_actionContoursExtraction_triggered()
// {
//     // QVector3D plane_norm = QVector3D(cos(qDegreesToRadians(45.0f)), 0, sin(qDegreesToRadians(45.0f))).normalized();
//     QVector3D plane_norm = QVector3D(1, 0, 0).normalized();
//     QVector3D axis = QVector3D(0, 0, 1).normalized();
//     float stride = 0.002f;
//     QVector<float> slice_lambdas;
//     xLog << "start";
//     auto preprocessed_partitions = m_model_slices_producer.preprocessModelDataAlongDirection(m_sptr_modelLoader->getEdges(), plane_norm);
//     xLog << "step 1";
//     m_model_slices_producer.generateSlicesLambda(preprocessed_partitions, stride, slice_lambdas);
//     xLog << "step 2";
//     const QVector<Triangle>& model_triangles = m_sptr_modelLoader->getTriangles();
//     qsizetype numSlices = slice_lambdas.size();
//     QVector<QVector<QVector<Vertex>>> resultant_contours(numSlices);

//     // 定义旋转角度
//     const float rotation_angle = qDegreesToRadians(1.14530502f);

//     std::for_each(std::execution::par, resultant_contours.begin(), resultant_contours.end(),
//                   [&](auto& slice) {
//                       int i = &slice - &resultant_contours[0];
//                       QVector<QVector<Vertex>> contours_3d;
//                       QVector<Edge> contour_edges;
//                       QVector<Triangle> proper_meshes = h0(model_triangles, plane_norm, slice_lambdas[i]);
//                       h1(proper_meshes, plane_norm, slice_lambdas[i], contour_edges);
//                       h2(contour_edges, contours_3d);

//                       // 获取原始切片轮廓
//                       slice = std::move(contours_3d);

//                       // 让 plane_norm 绕着 axis 分别旋转 -a 和 +a 弧度
//                       QVector3D plane_norm_neg = rotateVector(plane_norm, axis, -rotation_angle).normalized();
//                       QVector3D plane_norm_pos = rotateVector(plane_norm, axis, rotation_angle).normalized();

//                       // 再次使用h0,h1,h2获取slice_na,slice_pa
//                       QVector<QVector<Vertex>> slice_na, slice_pa;

//                       float lambda_neg = slice_lambdas[i] * cos(rotation_angle);
//                       float lambda_pos = slice_lambdas[i] * cos(rotation_angle);

//                       // 负角度切片
//                       QVector<Triangle> proper_meshes_neg = h0(model_triangles, plane_norm_neg, lambda_neg);
//                       QVector<Edge> contour_edges_neg;
//                       h1(proper_meshes_neg, plane_norm_neg, lambda_neg, contour_edges_neg);
//                       h2(contour_edges_neg, slice_na);

//                       // 正角度切片
//                       QVector<Triangle> proper_meshes_pos = h0(model_triangles, plane_norm_pos, lambda_pos);
//                       QVector<Edge> contour_edges_pos;
//                       h1(proper_meshes_pos, plane_norm_pos, lambda_pos, contour_edges_pos);
//                       h2(contour_edges_pos, slice_pa);

//                       // 将slice_na和slice_pa的点分别旋转 +a 和 -a 弧度与原切片平行
//                       rotateContours(slice_na, axis, rotation_angle);      // 旋转 +a 弧度
//                       rotateContours(slice_pa, axis, -rotation_angle);     // 旋转 -a 弧度

//                       // 合并到slice里
//                       for (auto& contour : slice_na) {
//                           slice.append(contour);
//                       }
//                       for (auto& contour : slice_pa) {
//                           slice.append(contour);
//                       }

//                       // 根据距离δ=1e-6去重一些顶点
//                       removeDuplicateVertices(slice, 1e-6f);
//                   }
//                   );
//     xLog << "step 3";
//     save3DContoursToJson(resultant_contours, slice_lambdas, plane_norm, "contours3D.json");
//     xLog << "step 4";
// }

// void generateEdgeDensityJSON(const QVector<QPair<QPair<float, float>, Edge>>& preprocessed_partitions,
//                              float stride, float m_lowest, float m_highest, const QString& filename)
// {
//     if (preprocessed_partitions.isEmpty() || stride <= 0) {
//         return;
//     }

//     // 获取全局范围（假设m_lowest和m_highest是类成员变量）
//     float global_min = m_lowest;
//     float global_max = m_highest;

//     // 创建采样点
//     QJsonObject jsonData;
//     QJsonArray xValues;
//     QJsonArray yValues;

//     // 采样点数量
//     int sample_count = static_cast<int>((global_max - global_min) / stride) + 1;

//     // 对每个采样点计算覆盖的区间数量
//     for (int i = 0; i < sample_count; ++i) {
//         float x = global_min + i * stride;

//         // 计算在x位置有多少个区间覆盖
//         int count = 0;
//         for (const auto& partition_pair : preprocessed_partitions) {
//             const QPair<float, float>& partition = partition_pair.first;
//             float a = partition.first;  // 较大值
//             float b = partition.second; // 较小值

//             // 检查x是否在区间[b, a]内
//             if (x >= b && x <= a) {
//                 count++;
//             }
//         }

//         xValues.append(static_cast<double>(x));
//         yValues.append(count);
//     }

//     // 构建JSON对象
//     jsonData["global_min"] = global_min;
//     jsonData["global_max"] = global_max;
//     jsonData["stride"] = static_cast<double>(stride);
//     jsonData["x_values"] = xValues;
//     jsonData["y_values"] = yValues;

//     // 保存到文件
//     QJsonDocument doc(jsonData);
//     QFile file(filename);
//     if (file.open(QIODevice::WriteOnly)) {
//         file.write(doc.toJson());
//         file.close();
//     }
// }

void Domain::on_actionContoursExtraction_triggered()
{
    m_sptr_slicingSetting->show();
}

void Domain::on_actionRadialGrayScaleConvertion_triggered()
{
    m_sptr_modelDisplayer->applyRadialGrayscaleValues();
}

void Domain::on_actionGlobalGrayScaleConvertion_triggered()
{
    m_sptr_modelDisplayer->applyGlobalGrayscaleValues();
}

void Domain::on_actionGrayScaleConvertionCancel_triggered()
{
    m_sptr_modelDisplayer->cancelGrayscaleConvertion();
}

void Domain::on_actionPureColorSetting_triggered()
{
    m_sptr_modelColorPalette->openColorDialog();
}

void Domain::on_actionCancelPureColor_triggered()
{
    m_sptr_modelDisplayer->cancelPureColorConvertion();
}

void Domain::on_actionPreview_triggered()
{
    m_sptr_previewDirectionSelector->show();
}

void Domain::on_actionModelScaling_triggered()
{
    m_sptr_modelDisplayer->resizeModel(0.027f);
}

